package com.xindacloud.sms.portal.controller;


import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.gson.Gson;
import com.xindacloud.sms.portal.constant.SessionKeys;
import com.xindacloud.sms.portal.dto.LoginParamDTO;
import com.xindacloud.sms.portal.entity.SmsUser;
import com.xindacloud.sms.portal.exception.ServiceException;
import com.xindacloud.sms.portal.service.ISmsUserService;
import com.xindacloud.sms.portal.utils.UnionResultHelp;
import com.xindacloud.sms.portal.vo.SmsUserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Objects;
import java.util.Optional;


@SuppressWarnings("ALL")
@Api(tags = {"portal登录相关接口"})
@RestController
@RequestMapping(value = "/api/v1/portal/user")
public class AccountController {

    private final DefaultKaptcha defaultKaptcha;

    private final ISmsUserService smsUserService;

    @Autowired
    public AccountController(DefaultKaptcha defaultKaptcha, ISmsUserService smsUserService) {
        this.defaultKaptcha = defaultKaptcha;
        this.smsUserService = smsUserService;
    }

    @ApiOperation(value = "登录", response = SmsUserVO.class)
    @PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object login(@ApiParam(name = "parameters", value = "登录参数", required = true)
                        @RequestBody @Valid LoginParamDTO parameters,
                        HttpServletRequest request) {

        HttpSession session = request.getSession(false);
        if (Objects.isNull(session)) {
            throw new ServiceException("未找到会话信息.", UnionResultHelp.StatusEnum.FailToken.code());
        } else {
            String sessionVerificationCode = Optional.ofNullable(session.getAttribute(SessionKeys.VCODE))
                    .map(String::valueOf)
                    .orElse("");
            boolean checkEqualsVerificationCode = sessionVerificationCode.equalsIgnoreCase(parameters.getVerificationCode());
            if (checkEqualsVerificationCode) {
                final SmsUserVO smsUser = smsUserService.login(parameters.getUsername(), parameters.getPassword());
                if (Objects.nonNull(smsUser)) {
                    session.setAttribute(SessionKeys.ACCOUNT, smsUser);
                    return smsUser;
                } else {
                    throw new ServiceException("账号或密码错误.", UnionResultHelp.StatusEnum.FailLogin.code());
                }
            } else {
                throw new ServiceException("验证码错误.", UnionResultHelp.StatusEnum.FailVCode.code());
            }
        }

    }


    @ApiOperation(value = "退出登录", response = UnionResultHelp.class)
    @PostMapping(value = "/login-out")
    public void loginOut(HttpServletRequest request, HttpServletResponse resp) throws IOException {

        HttpSession session = request.getSession(false);
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("application/json; charset=utf-8");
        if (Objects.isNull(session)) {
            resp.setStatus(UnionResultHelp.StatusEnum.FailToken.code());
            resp.getWriter().write(new Gson().toJson(new UnionResultHelp(UnionResultHelp.StatusEnum.FailToken, "未找到会话信息或登录会话已失效,请重新登录.")));
            return;
        } else {
            session.invalidate();
        }
        resp.getWriter().write(new Gson().toJson(new UnionResultHelp(UnionResultHelp.StatusEnum.Success, "退出登录成功")));
    }

    @ApiOperation(value = "获取验证码,返回Base64编码",
            response = UnionResultHelp.class)
    @GetMapping(value = "/verification-code", produces = MediaType.APPLICATION_JSON_VALUE)
    public Object vcode(HttpServletRequest request, HttpServletResponse response) throws IOException {

        byte[] imageByte = null;
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();

        // Save
        String createText = defaultKaptcha.createText();
        request.getSession().setAttribute(SessionKeys.VCODE, createText);

        BufferedImage challenge = defaultKaptcha.createImage(createText);
        ImageIO.write(challenge, "png", jpegOutputStream);

        imageByte = jpegOutputStream.toByteArray();
        response.setHeader("Access-Control-Expose-Headers", SessionKeys.SMS_TOKEN);
        return "data:image/png;base64," + Base64Utils.encodeToString(imageByte);

    }

    @ApiOperation(value = "注册用户")
    @PostMapping(value = "/registerUser")
    public Object registerUser(@RequestBody SmsUser smsUser) {
        return smsUserService.registerUser(smsUser);
    }

    @ApiOperation(value = "修改密码")
    @PostMapping(value = "/updateUserPassword")
    public Object updateUserPassword(@RequestBody SmsUser smsUser) {
        return smsUserService.updateUserPassword(smsUser);
    }
    
    @ApiOperation(value = "根据用户ID查询用户详情", response = SmsUser.class)
    @PostMapping(value = "/getUserDetail")
    public Object getUserDetail(@ApiParam(name = "user", value = "用户", required = true)
                                @RequestBody SmsUser smsUser) {
        return smsUserService.getUserDetail(smsUser.getUserId());
    }


}
